package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.constants.MQConstants;
import com.heima.common.controller.AbstractController;
import com.heima.common.dtos.PageInfo;
import com.heima.common.dtos.PageRequestDto;
import com.heima.common.dtos.Result;
import com.heima.common.exception.AppHttpCodeEnum;
import com.heima.common.exception.LeadNewsException;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsSaveDto;
import com.heima.model.wemedia.dtos.WmNewsVo;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.BeanHelper;
import com.heima.utils.common.JsonUtils;
import com.heima.utils.common.ThreadLocalUtils;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.WmNewsService;
import org.apache.commons.lang3.StringUtils;
import org.apache.kafka.clients.KafkaClient;
import org.apache.kafka.clients.admin.KafkaAdminClient;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaAdmin;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 自媒体图文内容信息表 服务实现类
 * </p>
 *
 * @author heima
 * @since 2021-08-06
 */
@Service
@Transactional
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {
    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;
    @Autowired
    private WmMaterialMapper wmMaterialMapper;
    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;
    @Autowired
    private WmNewsMapper wmNewsMapper;


    @Override
    public Result<PageInfo<WmNews>> searcheNews(PageRequestDto dto) {

        IPage<WmNews> iPage = new Page<>(dto.getPage(), dto.getSize());

        QueryWrapper<WmNews> queryWrapper = new QueryWrapper<>();

        WmNewsDto body = (WmNewsDto) dto.getBody();
        if (body != null) {
            //关键词
            if (StringUtils.isNotEmpty(body.getKeyword())) {
                queryWrapper.like("title", body.getKeyword());
            }
            //状态
            if (body.getStatus() != null) {
                queryWrapper.eq("status", body.getStatus());
            }
            //频道
            if (body.getChannelId() != null) {
                queryWrapper.eq("channelId_id", body.getChannelId());
            }
            //发布时间
            if (body.getBeginPubDate() != null && body.getEndPubDate() != null) {
                queryWrapper.between("publish_time", body.getBeginPubDate(), body.getEndPubDate());
            }
            //获取登录用户
            WmNews wmNews = (WmNews) ThreadLocalUtils.get();
            if (wmNews == null) {
                throw new LeadNewsException(AppHttpCodeEnum.TOKEN_INVALID);
            }
        }
        //按照created_time倒序
        queryWrapper.orderByDesc("created_time");
        //查询数据获取数据
        iPage = page(iPage, queryWrapper);

//        PageInfo<WmNews> pageInfo = new PageInfo<>(dto.getPage(),dto.getSize(),iPage.getTotal(),iPage.getRecords());
        PageInfo<WmNews> pageInfo = new PageInfo<>(dto.getPage(), dto.getSize(), iPage.getTotal(), iPage.getPages(), iPage.getRecords());
        return Result.ok(pageInfo);

    }

    @Override
    public Result submitNews(WmNewsSaveDto dto) {
        WmUser wmUser = (WmUser) ThreadLocalUtils.get();
        if (wmUser == null) {
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }

        try {
            //准备好WmNews对象数据
            //1）从WmNewsSaveDto拷贝数据到WmNews对象
            WmNews wmNews = BeanHelper.copyProperties(dto, WmNews.class);
            //2）补充数据
            wmNews.setUserId(wmUser.getId());
            wmNews.setSubmitedTime(new Date());
            //3）处理并设置封面图片
            if (CollectionUtils.isNotEmpty(dto.getImages())) {
                wmNews.setImages(dto.getImages().stream().collect(Collectors.joining(",")));
            }

            //处理自动封面的情况
            //获取到文章内容的图片
            List<String> contentImages = getImagesFromContent(dto.getContent());
            if (dto.getType().equals(-1)) {
                if (contentImages.size() == 0) {
                    //无图
                    wmNews.setImages("");
                    wmNews.setType(0);
                }
                if (contentImages.size() >= 1 && contentImages.size() <= 2) {
                    //单图
                    wmNews.setImages(contentImages.get(0));
                    wmNews.setType(1);
                }
                if (contentImages.size() >= 3) {
                    //三图
                    //截取前三张图
                    contentImages = contentImages.subList(0, 3);
                    wmNews.setImages(contentImages.stream().collect(Collectors.joining(",")));
                    wmNews.setType(3);
                }
            }

            //判断是否为新增还是修改
            if (dto.getId() == null) {
                //新增
                wmNews.setCreatedTime(new Date());
                save(wmNews);
            } else {
                //修改
                wmNews.setSubmitedTime(new Date());
                updateById(wmNews);

                //删除该文章和素材联系
                QueryWrapper<WmNewsMaterial> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("news_id", dto.getId());
                wmNewsMaterialMapper.delete(queryWrapper);
            }

            //4）判断草稿还是提交
            //如果是提交请求，才新增文章和素材的关联
            if (dto.getStatus().equals(WmNews.Status.SUBMIT.getCode())) {

                //1）添加内容图片与文章的关联
                if (CollectionUtils.isNotEmpty(contentImages)) {
                    //通过素材的URL获取到素材ID
                    List<Integer> materialIds = getMaterialIdsFromUrl(contentImages);
                    //批量添加
                    wmNewsMaterialMapper.saveNewsMaterials(materialIds, wmNews.getId(), 0);
                }

                //建立封面图片 与 文章 联系
                String images = wmNews.getImages();
                if (StringUtils.isNotEmpty(images)) {
                    List<Integer> materialIds = getMaterialIdsFromUrl(Arrays.asList(images.split(",")));

                    //批量添加
                    wmNewsMaterialMapper.saveNewsMaterials(materialIds, wmNews.getId(), 1);
                }

            }
            if (dto.getStatus().equals(WmNews.Status.SUBMIT.getCode())) {
                kafkaTemplate.send(MQConstants.WM_NEWS_AUTO_SCAN_TOPIC, wmNews.getId() + "");

            }

            return Result.ok();
        } catch (Exception e) {
            e.printStackTrace();
            throw new LeadNewsException(AppHttpCodeEnum.SERVER_ERROR);
        }
    }

    @Override
    public Result delNews(Integer id) {
        WmNews wmNews = getById(id);
        if (wmNews == null) {
            throw new LeadNewsException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        try {
            removeById(id);
            QueryWrapper<WmNewsMaterial> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("news_id", id);
            wmNewsMaterialMapper.delete(queryWrapper);
            return Result.ok();
        } catch (Exception e) {
            e.printStackTrace();
            throw new LeadNewsException(AppHttpCodeEnum.SERVER_ERROR);
        }


    }

    /**
     * 文章上下架
     */

    @Override
    public Result downOrUp(Map<String, Object> map) {
        //判断是否登录
        WmUser wmUser = (WmUser) ThreadLocalUtils.get();
        if (wmUser == null) {
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }
        Integer id = (Integer) map.get("id");
        Integer enable = (Integer) map.get("enable");
        WmNews wmNews = getById(id);
        if (wmNews == null) {
            throw new LeadNewsException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        try {
            wmNews.setEnable(enable);
            updateById(wmNews);

            //使用MQ同步App文章的上下架状态
            //App文章ID 状态值
            HashMap<String, Object> msgMap = new HashMap<>();
            msgMap.put("enble", enable);
            msgMap.put("apArticleId", wmNews.getArticleId());
            kafkaTemplate.send(MQConstants.WM_NEWS_UP_OR_DOWN_TOPIC, JsonUtils.toString(msgMap));
            return Result.ok();

        } catch (Exception e) {
            e.printStackTrace();
            throw new LeadNewsException(AppHttpCodeEnum.SERVER_ERROR);
        }


    }

    /**
     * 查询待审核的文章列表
     */
    @Override
    public Result<PageInfo<WmNewsVo>> searchNewsByCondition(PageRequestDto<WmNews> dto) {
        WmNews body = dto.getBody();
        String keyword = "";
        if (body != null && StringUtils.isNotEmpty(body.getTitle())) {
            keyword = "%" + body.getTitle() + "%";
        }
        if (dto.getPage() == null) dto.setPage(1L);
        if (dto.getSize() == null) dto.setSize(10L);
        Long start = (dto.getPage() - 1) * dto.getSize();
        //2.查询数据，获取结果
        //查询待审核文章的每页的列表数据
        try {
            List<WmNewsVo> list = wmNewsMapper.searchNewsByCondition(keyword, start, dto.getSize());
            Long total = wmNewsMapper.searchCountNewsByCondition(keyword);
            long totalPage = 0;
            if (total % dto.getSize() == 0) {
                totalPage = totalPage / dto.getSize();
            } else {
                totalPage = total / dto.getSize() + 1;
            }

            PageInfo<WmNewsVo> pageInfo = new PageInfo<>(dto.getPage(), dto.getSize(), total, totalPage, list);
            return Result.ok(pageInfo);
        } catch (Exception e) {
            e.printStackTrace();
            throw new LeadNewsException(AppHttpCodeEnum.SERVER_ERROR);
        }


    }
    /**
     * 查询待定时发布的文章
     */
    @Override
    public Result<List<WmNews>> findRelease() {
        try {
            QueryWrapper<WmNews> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("statu",WmNews.Status.SUCCESS.getCode());
            queryWrapper.le("publish_time",new Date());
            return Result.ok(list(queryWrapper));
        } catch (Exception e) {
            e.printStackTrace();
            throw new LeadNewsException(AppHttpCodeEnum.SERVER_ERROR);
        }


    }

    /**
     * 通过素材的URL地址取出素材的Id列表
     *
     * @param contentImages
     * @return
     */
    private List<Integer> getMaterialIdsFromUrl(List<String> contentImages) {
        QueryWrapper<WmMaterial> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("url", contentImages);
        List<WmMaterial> wmMaterials = wmMaterialMapper.selectList(queryWrapper);
        return wmMaterials.stream().map(WmMaterial::getId).collect(Collectors.toList());
    }

    /**
     * 提取内容中的所有图片的地址
     *
     * @param content
     * @return
     */
    private List<String> getImagesFromContent(String content) {
        List<Map<String, String>> list = JsonUtils.toBean(content, List.class);

        List<String> imageList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (Map<String, String> map : list) {
                if (map.get("type").equals("image")) {
                    imageList.add(map.get("value"));
                }
            }
        }
        return imageList;
    }
}


